package com.lunago.agent.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.alibaba.fastjson.JSON;
import com.lunago.agent.constant.JsonResult;
import com.lunago.agent.constant.ServiceCode;
import com.lunago.agent.jwt.CryptogramUtil;
import com.lunago.agent.jwt.JwtPayLoad;
import com.lunago.agent.jwt.JwtTokenUtil;
import com.lunago.agent.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 这个过滤器，在所有请求之前，也在spring security filters之前
 * <p>
 * 这个过滤器的作用是：接口在进业务之前，添加登录上下文（SecurityContext）
 * <p>
 * 因为现在没有用session了，只能token来校验当前的登录人的身份，所以在进业务之前要给当前登录人设置登录状态
 *
 * @author yubaoshan，xuyuxiang
 * @date 2020/4/11 13:02
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final Log log = Log.get();

    @Autowired
    private AuthService authService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException {
        try {
            doFilter(request, response, filterChain);
        } catch (Exception e) {
            log.error(">>> 服务器运行异常，请求号为：{}，具体信息为：{}", e.getMessage());
        }
    }

    private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        try {
            String token = authService.getTokenFromRequest(request);
            token = CryptogramUtil.doDecrypt(token);
            if (StrUtil.isNotEmpty(token)) {
                JwtPayLoad payload = JwtTokenUtil.getJwtPayLoad(token);
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(payload, null, null);
                authService.setSpringSecurityContextAuthentication(payload);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
//            JwtPayLoad payload = new JwtPayLoad();
//            payload.setUserId(100000001l);
//            payload.setAccount("liu wei");
//            payload.setFirstName("wei");
//            payload.setLastName("liu");
//            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(payload, null, null);
//            authService.setSpringSecurityContextAuthentication(payload);
//            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (RuntimeException ae) {
            ae.printStackTrace();
            //token过期或者token失效的情况，响应给前端
            log.error("解析JWT时出现异常：JwtException");
            String message = "解析JWT时出现异常：JwtException";
            JsonResult jsonResult = JsonResult.fail(ServiceCode.ERR_JWT_EXPIRED, message);
            PrintWriter writer = response.getWriter();
            writer.println(JSON.toJSONString(jsonResult));
            writer.close();
            return;
        }
        // 3.其他情况放开过滤
        filterChain.doFilter(request, response);

    }

}
